<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/12/6/006
 * Time: 10:35
 */

namespace app\api\model;


use app\api\service\Token;
use app\api\model\Address as AddressModel;
use app\api\model\Product as ProductModel;
use app\api\model\ProductAttr as ProductAttrModel;
use app\api\model\AttrValue as AttrValueModel;
use app\lib\exception\OrderException;
use app\lib\exception\ProductAttrException;
use app\lib\exception\ProductException;
use app\lib\exception\AddressException;
use app\api\model\Member as MemberModel;
use app\api\service\Order as OrderService;
use app\api\model\OrderBuyProduct as OrderBuyProductModel;
use think\Db;
use think\Exception;

class OrderBuy extends BaseModel {

    protected $hidden = ['update_time','create_time'];
    /**
     * 订单用户
     * @return \think\model\relation\belongsTo
     */
    public function orderMember() {
        return $this->belongsTo('Member');
    }

    /**
     * 订单产品
     * @return \think\model\relation\hasOne
     */
    public function orderBuyProduct() {
        return $this->hasOne('OrderBuyProduct');
    }

    /**
     * 订单售后
     * @return \think\model\relation\hasOne
     */
    public function orderBuyAfterSale() {
        return $this->hasOne('OrderBuyAfterSale');
    }

    /**
     * 获取用户订单列表
     * @param $status
     * @param $comment_status
     * @return \think\Paginator
     */
    public static function getMemberOrderBuyList($status, $comment_status) {

        $uid = Token::getCurrentUid();

        if ($status > 0) {
            $where[] = ['status', '=', $status];
            if ($status == 6) {
                $where[] = ['comment_status', '=', 0];
                $where[] = ['after_sale_status', 'in', '0, 2'];
            }
        }

        if ($comment_status > 0) {
            $where[] = ['comment_status', '=', $comment_status];
        }

        $where[] = ['member_id', '=', $uid];

        $orders = self::with('orderBuyProduct.product.brand')->where($where)->order('id desc')->paginate(5, true);

        foreach ($orders as &$order) {
            $order->order_buy_product->product->visible(['brand']);
            $order->status_text = self::get_order_buy_status_text($order->status, $order->after_sale_status, $order->comment_status);
        }

//        echo self::getLastSql();

        return $orders;
    }

    /**
     * 获取商城订单状态信息
     * @param $status
     * @param $after_sale_status
     * @param $comment_status
     * @return mixed|string
     */
    public static function get_order_buy_status_text($status, $after_sale_status, $comment_status) {
        $status_array = ['', '待付款', '已付款', '已发货', '', '', '已签收', '完成', '已关闭', '已退款', 99 => '已发货'];
        if ($status == 6 || $status == 3) {
            if ($after_sale_status == 1) {
                return '申请售后';
            }

            if ($after_sale_status == 2) {
                return '售后处理中';
            }

            if ($comment_status == 0) {
                return '待评价';
            }
        }
        return $status_array[$status];
    }


    /**
     * 确认订单数据
     * @param $id
     * @param $attr_group_id
     * @param $num
     * @return array
     * @throws ProductException
     * @throws \Exception
     */
    public static function bookingQuantityBody($id, $attr_group_id, $num) {

        $uid = Token::getCurrentUid();

        $address = AddressModel::getDefaultAddressInfo($uid);

        $product = ProductModel::getProductInfo($id, 2);
        if (!$product) {
            throw new ProductException();
        }

        $product->visible(['id', 'name', 'price', 'thumb', 'brand', 'category']);

        $attr = [];
        if ($attr_group_id > 0) {
            $attr_data = self::checkAttrInventory($id, $attr_group_id, $num);
            $product['price'] = $attr_data['price'];
            $attr = $attr_data['attr'];
        }

        return [
            'address' => $address,
            'product' => $product,
            'attr' => $attr,
            'num' => $num,
            'product_attr_id' => $attr_group_id,
            'order' => [
                'price' => $product['price'] * $num
            ]
        ];
    }

    /**
     * 验证产品属性库存
     * @param $id
     * @param $attr_group_id
     * @param $num
     * @return array
     * @throws ProductAttrException
     * @throws ProductException
     */
    public static function checkAttrInventory($id, $attr_group_id, $num) {
        $attr_group = ProductAttrModel::get(['product_id' => $id, 'id' => $attr_group_id]);
        if (!$attr_group) {
            throw new ProductAttrException();
        }

        if ($attr_group['inventory'] < $num) {
            throw new ProductException([
                'msg' => '库存不足',
                'errorCode' => 80002
            ]);
        }
        $price = $attr_group['price']; // 更新产品价格

        $attrs = AttrValueModel::getAttrValueNameByIds($attr_group['attr_group']);
        $attr = implode(' / ', $attrs);
        return [
            'price' => $price,
            'attr' => $attr
        ];
    }

    /**
     * 获取用户购买订单数量，可指定状态
     * @param $uid
     * @param int $status
     * @return int|string
     */
    public static function getMemberOrderBuyCount($uid, $status = 0) {
        $where[] = ['member_id' ,'=', $uid];
        if ($status > 0) {
            $where[] = ['status', '=',  $status];
            if ($status == 6) {
                $where[] = ['comment_status', '=', 0];
                $where[] = ['after_sale_status', 'in', '0, 2'];
            }
        }
        return self::where($where)->count();
    }

    /**
     * 创建订单
     * @param $id
     * @param $address_id
     * @param $attr_group_id
     * @param $num
     * @param $source
     * @return $this
     * @throws AddressException
     * @throws OrderException
     */
    public static function createOrderBuy($id, $attr_group_id, $num , $address_id, $source) {

        $uid = Token::getCurrentUid();

        $address = AddressModel::getAddressInfoById($address_id, $uid);
        if (!$address) {
            throw new AddressException();
        }

        $quantity_order_data = self::bookingQuantityBody($id, $attr_group_id, $num);

        // 获取下单用户信息
        $member = MemberModel::get(['id' => $uid]);

        Db::startTrans();
        try {
            // 组装订单数据
            $order_data = [
                'order_sn' => OrderService::makeOrderNo('XS'),
                'member_id' => $uid,
                'price' => $quantity_order_data['order']['price'],
                'consignee' => $address['linkman'],
                'mobile' => $address['mobile'],
                'province' => $address['region_province']['region_name'],
                'city' => $address['region_city']['region_name'],
                'area' => $address['region_area']['region_name'],
                'address' => $address['address'],
                'source' => $source
            ];
            $order = self::create($order_data);

            if ($order) {
                //组装订单产品数据
                $order_product_data = [
                    'order_buy_id' => $order['id'],
                    'product_id' => $id,
                    'name' => $quantity_order_data['product']['name'],
                    'price' => $quantity_order_data['product']['price'],
                    'thumb' => $quantity_order_data['product']['thumb'],
                    'num' => $num,
                    'attr' => $quantity_order_data['attr'],
                    'product_attr_id' => $attr_group_id
                ];
                OrderBuyProductModel::create($order_product_data);

                // 订单创建成功  推送通知
                OrderService::sendCreateOrderMsg($order_data, '销售');

                // 检查用户订单数量，如果是首次下单，需要发送微信消息
                OrderService::checkMemberOrderNum($uid, $member, $order_data, '销售');
            } else {
                throw new OrderException([
                    'msg' => '订单创建失败',
                    'errorCode' => 60001
                ]);
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw new OrderException([
                'msg' => $e,
                'errorCode' => 60001
            ]);
        }

        return $order;
    }

    /**
     * 获取订单详情
     * @param $id
     * @return array|null|\PDOStatement|string|\think\Model
     */
    public static function getOrderBuyInfo($id) {

        $uid = Token::getCurrentUid();
        $order = self::with('orderBuyProduct.product.brand')->where('id', '=', $id)->where('member_id', '=', $uid)->find();

        if ($order) {
            $order->order_buy_product->product->visible(['brand']);
            $order['status_text']  =  self::get_order_buy_status_text($order['status'], $order['after_sale_status'], $order['comment_status']);
        }

        return $order;
    }

    /**
     * 根据ID删除商城订单
     * @param $id
     * @return bool
     * @throws Exception
     * @throws OrderException
     */
    public static function deleteOrderBuy($id) {
        $uid = Token::getCurrentUid();

        $order = self::get(['id' => $id, 'member_id' => $uid]);

        if (!$order) {
            throw new OrderException();
        }

        if ($order['status'] != 1) {
            throw new OrderException([
                'msg' => '订单状态异常，只有未付款订单可以删除',
                'errorCode' => 60002
            ]);
        }
        Db::startTrans();
        try {
            $order->orderBuyProduct->delete();
            $order->delete();
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw $e;
        }
        return true;
    }

    /**
     * 确认收货
     * @param $id
     * @return false|int
     * @throws OrderException
     */
    public static function orderBuyConfirmReceipt($id) {
        $uid = Token::getCurrentUid();

        $order = self::get(['id' => $id, 'member_id' => $uid]);

        if (!$order) {
            throw new OrderException();
        }

        if ($order['status'] != 3 && $order['status'] != 99) {
            throw new OrderException([
                'msg' => '订单状态异常，只有待收货订单可以确认收货',
                'errorCode' => 60002
            ]);
        }

        $rs = $order->save(['receipt_time' => time(), 'status' => 6]);
        return $rs;
    }

    /**
     * 获取物流信息
     * @param $express_sn
     * @return array
     */
    public static function expressInfo($express_sn) {

        $order = self::get(['express_sn' => $express_sn]);

        $data = OrderService::expressInfo($order, $express_sn, 'orderBuyProduct');

        return $data;
    }
}